/**
 * 手机号工具类 - JavaScript版本
 * 提供手机号校验、格式化、脱敏等常用功能，支持多国家手机号格式
 * 可直接复制粘贴使用，无需任何依赖
 */

/**
 * 手机号校验结果
 * @param {boolean} isValid - 是否有效
 * @param {string} message - 消息
 * @param {string} [country] - 国家代码
 */
function PhoneValidationResult(isValid, message, country) {
  this.isValid = isValid;
  this.message = message;
  this.country = country;
}

/**
 * 国家手机号规则配置
 */
function CountryPhoneRule(name, code, pattern, length, example) {
  this.name = name;
  this.code = code;
  this.pattern = pattern;
  this.length = length;
  this.example = example;
}

/**
 * 支持的国家手机号规则
 */
const COUNTRY_PHONE_RULES = {
  CN: new CountryPhoneRule('中国', '+86', /^1[3-9]\d{9}$/, [11], '13800138000'),
  US: new CountryPhoneRule('美国', '+1', /^[2-9]\d{2}[2-9]\d{2}\d{4}$/, [10], '2025551234'),
  UK: new CountryPhoneRule('英国', '+44', /^[1-9]\d{8,9}$/, [9, 10], '7700123456'),
  JP: new CountryPhoneRule('日本', '+81', /^[789]0\d{8}$/, [11], '9012345678'),
  KR: new CountryPhoneRule('韩国', '+82', /^1[0-9]\d{7,8}$/, [9, 10], '1012345678'),
  DE: new CountryPhoneRule('德国', '+49', /^1[5-7]\d{8,9}$/, [10, 11], '15123456789'),
  FR: new CountryPhoneRule('法国', '+33', /^[67]\d{8}$/, [9], '612345678'),
  AU: new CountryPhoneRule('澳大利亚', '+61', /^4\d{8}$/, [9], '412345678')
};

/**
 * 基础手机号校验
 * @param {string} phone - 手机号
 * @returns {PhoneValidationResult} 校验结果
 */
function validatePhone(phone) {
  if (!phone) {
    return new PhoneValidationResult(false, '手机号不能为空');
  }

  // 移除所有非数字字符（除了+号）
  const cleanPhone = phone.replace(/[^\d+]/g, '');
  
  if (cleanPhone.length < 7) {
    return new PhoneValidationResult(false, '手机号长度过短');
  }

  if (cleanPhone.length > 15) {
    return new PhoneValidationResult(false, '手机号长度过长');
  }

  return new PhoneValidationResult(true, '手机号格式正确');
}

/**
 * 检查手机号是否为空
 * @param {string|null|undefined} phone - 手机号
 * @returns {boolean} 是否为空
 */
function isPhoneEmpty(phone) {
  return !phone || phone.trim() === '';
}

/**
 * 校验带+号的国际手机号
 * @param {string} phone - 手机号
 * @returns {PhoneValidationResult} 校验结果
 */
function validateInternationalPhone(phone) {
  if (isPhoneEmpty(phone)) {
    return new PhoneValidationResult(false, '手机号不能为空');
  }

  // 检查是否以+号开头
  if (!phone.startsWith('+')) {
    return new PhoneValidationResult(false, '国际手机号必须以+号开头');
  }

  // 移除+号，获取国家代码和号码
  const withoutPlus = phone.substring(1);
  
  // 查找匹配的国家规则
  for (const [countryCode, rule] of Object.entries(COUNTRY_PHONE_RULES)) {
    if (withoutPlus.startsWith(rule.code.substring(1))) {
      const localNumber = withoutPlus.substring(rule.code.length - 1);
      
      if (rule.pattern.test(localNumber) && rule.length.includes(localNumber.length)) {
        return new PhoneValidationResult(true, `${rule.name}手机号格式正确`, countryCode);
      }
    }
  }

  return new PhoneValidationResult(false, '不支持的手机号格式或国家代码');
}

/**
 * 校验指定国家的手机号
 * @param {string} phone - 手机号
 * @param {string} countryCode - 国家代码 (如: CN, US, UK)
 * @returns {PhoneValidationResult} 校验结果
 */
function validateCountryPhone(phone, countryCode) {
  if (isPhoneEmpty(phone)) {
    return new PhoneValidationResult(false, '手机号不能为空');
  }

  const rule = COUNTRY_PHONE_RULES[countryCode.toUpperCase()];
  if (!rule) {
    return new PhoneValidationResult(false, `不支持的国家代码: ${countryCode}`);
  }

  // 移除所有非数字字符
  const cleanPhone = phone.replace(/\D/g, '');
  
  if (!rule.pattern.test(cleanPhone)) {
    return new PhoneValidationResult(false, `${rule.name}手机号格式不正确，示例: ${rule.example}`);
  }

  if (!rule.length.includes(cleanPhone.length)) {
    return new PhoneValidationResult(false, `${rule.name}手机号长度不正确，应为${rule.length.join('或')}位`);
  }

  return new PhoneValidationResult(true, `${rule.name}手机号格式正确`, countryCode.toUpperCase());
}

/**
 * 格式化手机号（添加+号）
 * @param {string} phone - 手机号
 * @param {string} countryCode - 国家代码
 * @returns {string} 格式化后的手机号
 */
function formatPhoneWithCountryCode(phone, countryCode) {
  if (isPhoneEmpty(phone)) {
    return '';
  }

  const rule = COUNTRY_PHONE_RULES[countryCode.toUpperCase()];
  if (!rule) {
    return phone;
  }

  // 移除所有非数字字符
  const cleanPhone = phone.replace(/\D/g, '');
  
  // 如果已经包含国家代码，直接返回
  if (phone.startsWith('+')) {
    return phone;
  }

  return `+${rule.code.substring(1)}${cleanPhone}`;
}

/**
 * 格式化手机号显示（添加分隔符）
 * @param {string} phone - 手机号
 * @param {string} [countryCode='CN'] - 国家代码
 * @returns {string} 格式化后的手机号
 */
function formatPhoneDisplay(phone, countryCode = 'CN') {
  if (isPhoneEmpty(phone)) {
    return '';
  }

  const rule = COUNTRY_PHONE_RULES[countryCode.toUpperCase()];
  if (!rule) {
    return phone;
  }

  // 移除所有非数字字符
  const cleanPhone = phone.replace(/\D/g, '');
  
  // 中国手机号格式化
  if (countryCode.toUpperCase() === 'CN' && cleanPhone.length === 11) {
    return `${cleanPhone.slice(0, 3)}-${cleanPhone.slice(3, 7)}-${cleanPhone.slice(7)}`;
  }

  // 美国手机号格式化
  if (countryCode.toUpperCase() === 'US' && cleanPhone.length === 10) {
    return `(${cleanPhone.slice(0, 3)}) ${cleanPhone.slice(3, 6)}-${cleanPhone.slice(6)}`;
  }

  // 默认格式化（每3位添加一个空格）
  return cleanPhone.replace(/(\d{3})(?=\d)/g, '$1 ');
}

/**
 * 获取支持的国家列表
 * @returns {Array<{code: string, name: string, example: string}>} 支持的国家列表
 */
function getSupportedCountries() {
  return Object.entries(COUNTRY_PHONE_RULES).map(([code, rule]) => ({
    code,
    name: rule.name,
    example: rule.example
  }));
}

/**
 * 从手机号中提取国家代码
 * @param {string} phone - 手机号
 * @returns {string|null} 国家代码或null
 */
function extractCountryCode(phone) {
  if (isPhoneEmpty(phone) || !phone.startsWith('+')) {
    return null;
  }

  const withoutPlus = phone.substring(1);
  
  for (const [countryCode, rule] of Object.entries(COUNTRY_PHONE_RULES)) {
    if (withoutPlus.startsWith(rule.code.substring(1))) {
      return countryCode;
    }
  }

  return null;
}

/**
 * 手机号脱敏处理
 * @param {string} phone - 手机号
 * @param {string} [maskChar='*'] - 掩码字符，默认为*
 * @returns {string} 脱敏后的手机号
 */
function maskPhone(phone, maskChar = '*') {
  if (isPhoneEmpty(phone)) {
    return '';
  }

  const cleanPhone = phone.replace(/\D/g, '');
  
  if (cleanPhone.length < 4) {
    return phone;
  }

  if (cleanPhone.length <= 7) {
    return `${cleanPhone.slice(0, 2)}${maskChar.repeat(cleanPhone.length - 4)}${cleanPhone.slice(-2)}`;
  }

  return `${cleanPhone.slice(0, 3)}${maskChar.repeat(cleanPhone.length - 6)}${cleanPhone.slice(-3)}`;
}

/**
 * 批量手机号校验结果
 * @param {boolean} isValid - 是否有效
 * @param {string} message - 消息
 * @param {Array<string>} validPhones - 有效手机号数组
 * @param {Array<Object>} invalidPhones - 无效手机号数组
 * @param {Array<string>} duplicatePhones - 重复手机号数组
 * @param {number} totalCount - 总数量
 * @param {number} validCount - 有效数量
 * @param {number} invalidCount - 无效数量
 * @param {number} duplicateCount - 重复数量
 * @param {number} emptyCount - 空值数量
 * @param {number} exceededCount - 超出数量
 */
function BatchPhoneValidationResult(isValid, message, validPhones, invalidPhones, duplicatePhones, totalCount, validCount, invalidCount, duplicateCount, emptyCount, exceededCount) {
  this.isValid = isValid;
  this.message = message;
  this.validPhones = validPhones;
  this.invalidPhones = invalidPhones;
  this.duplicatePhones = duplicatePhones;
  this.totalCount = totalCount;
  this.validCount = validCount;
  this.invalidCount = invalidCount;
  this.duplicateCount = duplicateCount;
  this.emptyCount = emptyCount || 0;
  this.exceededCount = exceededCount || 0;
}

/**
 * 批量手机号校验
 * @param {Array<string>} phones - 手机号数组
 * @param {Object} [config={}] - 校验配置
 * @returns {BatchPhoneValidationResult} 批量校验结果
 */
function validateBatchPhones(phones, config = {}) {
  const {
    maxCount = 1000,           // 默认最大1000个
    minCount = 1,              // 默认最少1个
    checkUnique = true,        // 默认检查唯一性
    countryCode = 'CN',        // 默认中国
    allowEmpty = false,        // 默认不允许空值
    strictMode = false         // 默认非严格模式
  } = config;

  const result = new BatchPhoneValidationResult(
    true,
    '批量校验完成',
    [],
    [],
    [],
    phones ? phones.length : 0,
    0,
    0,
    0,
    0,
    0
  );

  // 检查输入是否为空
  if (!phones || phones.length === 0) {
    result.isValid = false;
    result.message = '手机号列表不能为空';
    return result;
  }

  // 检查数量限制
  if (phones.length > maxCount) {
    result.isValid = false;
    result.message = `手机号数量超过限制，最多允许 ${maxCount} 个，当前 ${phones.length} 个`;
    result.exceededCount = phones.length - maxCount;
    return result;
  }

  if (phones.length < minCount) {
    result.isValid = false;
    result.message = `手机号数量不足，至少需要 ${minCount} 个，当前 ${phones.length} 个`;
    return result;
  }

  // 用于检查重复的手机号
  const phoneSet = new Set();
  const duplicateSet = new Set();

  // 逐个校验手机号
  for (const phone of phones) {
    // 检查是否为空
    if (isPhoneEmpty(phone)) {
      if (allowEmpty) {
        result.emptyCount++;
        continue;
      } else {
        result.invalidPhones.push({
          phone,
          reason: '手机号不能为空'
        });
        result.invalidCount++;
        continue;
      }
    }

    // 检查唯一性
    if (checkUnique) {
      const normalizedPhone = phone.replace(/\D/g, '');
      if (phoneSet.has(normalizedPhone)) {
        duplicateSet.add(normalizedPhone);
        result.duplicatePhones.push(phone);
        result.duplicateCount++;
        continue;
      }
      phoneSet.add(normalizedPhone);
    }

    // 校验手机号格式
    const validation = validateCountryPhone(phone, countryCode);
    if (validation.isValid) {
      result.validPhones.push(phone);
      result.validCount++;
    } else {
      result.invalidPhones.push({
        phone,
        reason: validation.message
      });
      result.invalidCount++;
    }
  }

  // 处理重复的手机号
  if (checkUnique && duplicateSet.size > 0) {
    result.duplicatePhones = Array.from(duplicateSet);
    result.duplicateCount = duplicateSet.size;
  }

  // 严格模式：所有号码必须有效
  if (strictMode && result.invalidCount > 0) {
    result.isValid = false;
    result.message = `严格模式：发现 ${result.invalidCount} 个无效号码，所有号码必须有效`;
  } else if (result.invalidCount > 0 || result.duplicateCount > 0) {
    result.isValid = false;
    result.message = `校验完成，发现 ${result.invalidCount} 个无效号码，${result.duplicateCount} 个重复号码`;
  } else {
    result.message = `校验完成，所有 ${result.validCount} 个手机号都有效`;
  }

  return result;
}

/**
 * 批量手机号校验（简化版本，保持向后兼容）
 * @param {Array<string>} phones - 手机号数组
 * @param {string} [countryCode='CN'] - 国家代码，默认为CN
 * @param {boolean} [checkUnique=true] - 是否检查唯一性，默认为true
 * @returns {BatchPhoneValidationResult} 批量校验结果
 */
function validateBatchPhonesSimple(phones, countryCode = 'CN', checkUnique = true) {
  return validateBatchPhones(phones, {
    countryCode,
    checkUnique,
    maxCount: 1000,
    minCount: 1,
    allowEmpty: false,
    strictMode: false
  });
}

/**
 * 批量手机号格式化
 * @param {Array<string>} phones - 手机号数组
 * @param {string} [countryCode='CN'] - 国家代码
 * @returns {Array<string>} 格式化后的手机号数组
 */
function formatBatchPhones(phones, countryCode = 'CN') {
  return phones
    .filter(phone => !isPhoneEmpty(phone))
    .map(phone => formatPhoneWithCountryCode(phone, countryCode));
}

/**
 * 批量手机号脱敏处理
 * @param {Array<string>} phones - 手机号数组
 * @param {string} [maskChar='*'] - 掩码字符，默认为*
 * @returns {Array<string>} 脱敏后的手机号数组
 */
function maskBatchPhones(phones, maskChar = '*') {
  return phones
    .filter(phone => !isPhoneEmpty(phone))
    .map(phone => maskPhone(phone, maskChar));
}

/**
 * 从手机号数组中提取唯一号码
 * @param {Array<string>} phones - 手机号数组
 * @returns {Array<string>} 去重后的手机号数组
 */
function getUniquePhones(phones) {
  const phoneSet = new Set();
  const uniquePhones = [];

  for (const phone of phones) {
    if (isPhoneEmpty(phone)) continue;
    
    const normalizedPhone = phone.replace(/\D/g, '');
    if (!phoneSet.has(normalizedPhone)) {
      phoneSet.add(normalizedPhone);
      uniquePhones.push(phone);
    }
  }

  return uniquePhones;
}

/**
 * 批量手机号分类
 * @param {Array<string>} phones - 手机号数组
 * @param {string} [countryCode='CN'] - 国家代码
 * @returns {Object} 分类结果
 */
function categorizeBatchPhones(phones, countryCode = 'CN') {
  const result = {
    valid: [],
    invalid: [],
    duplicates: [],
    empty: []
  };

  const phoneSet = new Set();
  const duplicateSet = new Set();

  for (const phone of phones) {
    // 空值检查
    if (isPhoneEmpty(phone)) {
      result.empty.push(phone);
      continue;
    }

    // 重复检查
    const normalizedPhone = phone.replace(/\D/g, '');
    if (phoneSet.has(normalizedPhone)) {
      duplicateSet.add(normalizedPhone);
      result.duplicates.push(phone);
      continue;
    }
    phoneSet.add(normalizedPhone);

    // 格式校验
    const validation = validateCountryPhone(phone, countryCode);
    if (validation.isValid) {
      result.valid.push(phone);
    } else {
      result.invalid.push({
        phone,
        reason: validation.message
      });
    }
  }

  return result;
}

/**
 * 手机号工具类 - 封装所有功能
 */
class PhoneUtils {
  constructor() {
    this.COUNTRY_PHONE_RULES = COUNTRY_PHONE_RULES;
  }

  /**
   * 基础手机号校验
   */
  validatePhone(phone) {
    return validatePhone(phone);
  }

  /**
   * 检查手机号是否为空
   */
  isPhoneEmpty(phone) {
    return isPhoneEmpty(phone);
  }

  /**
   * 校验带+号的国际手机号
   */
  validateInternationalPhone(phone) {
    return validateInternationalPhone(phone);
  }

  /**
   * 校验指定国家的手机号
   */
  validateCountryPhone(phone, countryCode) {
    return validateCountryPhone(phone, countryCode);
  }

  /**
   * 格式化手机号（添加+号）
   */
  formatPhoneWithCountryCode(phone, countryCode) {
    return formatPhoneWithCountryCode(phone, countryCode);
  }

  /**
   * 格式化手机号显示（添加分隔符）
   */
  formatPhoneDisplay(phone, countryCode = 'CN') {
    return formatPhoneDisplay(phone, countryCode);
  }

  /**
   * 获取支持的国家列表
   */
  getSupportedCountries() {
    return getSupportedCountries();
  }

  /**
   * 从手机号中提取国家代码
   */
  extractCountryCode(phone) {
    return extractCountryCode(phone);
  }

  /**
   * 手机号脱敏处理
   */
  maskPhone(phone, maskChar = '*') {
    return maskPhone(phone, maskChar);
  }
}

// 创建全局实例
const phoneUtils = new PhoneUtils();

// 导出所有功能（支持多种使用方式）
if (typeof module !== 'undefined' && module.exports) {
  // Node.js环境
  module.exports = {
    PhoneUtils,
    phoneUtils,
    validatePhone,
    isPhoneEmpty,
    validateInternationalPhone,
    validateCountryPhone,
    formatPhoneWithCountryCode,
    formatPhoneDisplay,
    getSupportedCountries,
    extractCountryCode,
    maskPhone,
    COUNTRY_PHONE_RULES
  };
} else if (typeof window !== 'undefined') {
  // 浏览器环境
  window.PhoneUtils = PhoneUtils;
  window.phoneUtils = phoneUtils;
  window.validatePhone = validatePhone;
  window.isPhoneEmpty = isPhoneEmpty;
  window.validateInternationalPhone = validateInternationalPhone;
  window.validateCountryPhone = validateCountryPhone;
  window.formatPhoneWithCountryCode = formatPhoneWithCountryCode;
  window.formatPhoneDisplay = formatPhoneDisplay;
  window.getSupportedCountries = getSupportedCountries;
  window.extractCountryCode = extractCountryCode;
  window.maskPhone = maskPhone;
  window.COUNTRY_PHONE_RULES = COUNTRY_PHONE_RULES;
}
